﻿using System.Threading.Tasks;
using BizModels;
using BizModels.Common;
using IRepositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Microsoft.Owin;
using Repositories;
using ViewModels.BoardVM;
using ViewModels.CommonVM;
using WebLib.FileUpload;
using WebLib;
using WebLib.AuthorizeService;

namespace HinokyWeb.Controllers
{
    public class BoardController : BaseController
    {
        private IBoardRepository _boardRepository;
        private IBoardAutoSaveRepository _boardAutoSaveRepository;
        private ICategoryRepository _categoryRepository;

        private bool _isAdmin = MemberInfo.Instance.IsSignIn && MemberInfo.Instance.UserRole.Contains("ADMIN");

        public BoardController()
        {
            _boardRepository = new BoardRepository();
            _boardAutoSaveRepository = new BoardAutoSaveRepository();
            _categoryRepository = new CategoryRepository();
        }

        [HttpGet]
        public ActionResult Index()
        {
            var boardList = GetBoardList(false, _isAdmin);

            return View("List", boardList);
        }

        [HttpGet]
        public ActionResult List()
        {
            var boardList = GetBoardList(false, _isAdmin);

            return View(boardList);
        }

        [HttpGet]
        public ActionResult Details(int id = 0)
        {
            var searchT = new BoardSearchSingleT
            {
                Idx = id,
                IsIncludeDeleteItem = false,
                IsIncludeDisplayNoneItem = _isAdmin
            };

            var boardData = _boardRepository.GetBoard(searchT);

            ViewBag.Pamameters = Request.QueryString;

            var boardcreateVM = new BoardDetailVM
            {
                BoardData = new BoardVM
                {
                    Idx = boardData.Idx,
                    Title = HttpUtility.HtmlDecode(boardData.Title),
                    Body = HttpUtility.HtmlDecode(boardData.Contents),
                    Categories = boardData.Categories.ToArray(),
                    SearchTag = boardData.SearchTag,
                    IsDisplay = boardData.IsDisplay,
                    WriteDate = boardData.UpdateDate == null ? boardData.InsertDate.ToString("yyyy-MM-dd HH:mm") : ((DateTime)boardData.UpdateDate).ToString("yyyy-MM-dd HH:mm"),
                    WriteUserName = boardData.InsertUser.Name,
                    WriteUserId = boardData.InsertUser.UserID
                }
            };

            return View(boardcreateVM);
        }

        [HttpGet]
        [Authorize(Roles = "ADMIN")]
        public ActionResult Create()
        {
            ViewBag.IsExistAutoSave = false;
            
            var list = _boardAutoSaveRepository.GetBoardAutoSaveList(MemberInfo.Instance.UserKey);
            if (list.Count > 0)
                ViewBag.IsExistAutoSave = true;

            return View();
        }

        [HttpPost]
        [Authorize(Roles = "ADMIN")]
        public ActionResult Create(BoardCreateVM model)
        {
            var data = new BoardT
            {
                Contents = model.Body,
                Title = model.Title,
                SearchTag = model.SearchTag,
                IsDisplay = model.IsDisplay,
                InsertUser = new MemberT { UserKey = MemberInfo.Instance.UserKey }
            };

            if (model.Categories != null)
            {
                data.Categories = model.Categories.Where(s => !string.IsNullOrEmpty(s)).Distinct().ToList();
            }

            var nIdx = _boardRepository.AddBoard(data);

            // 등록한 글 다시 조회
            if (nIdx > 0)
            {
                var searchT = new BoardSearchSingleT
                {
                    Idx = nIdx,
                    IsIncludeDeleteItem = false,
                    IsIncludeDisplayNoneItem = _isAdmin
                };

                var nData = _boardRepository.GetBoard(searchT);

                return
                    Json(
                        new
                        {
                            Success = true,
                            Idx = nIdx,
                            Contents = WebHelper.StripTagsCharArray(HttpUtility.HtmlDecode(nData.Contents))
                        });
            }

            // 임시저장 데이터 삭제
            if (nIdx > 0)
            {
                _boardAutoSaveRepository.RemoveBoardAutoSave(model.AutoSaveIdx, MemberInfo.Instance.UserKey);
            }

            return Json(new {Success = false, Idx = 0});
        }

        [HttpGet]
        [Authorize(Roles = "ADMIN")]
        public ActionResult Edit(int id)
        {
            var boardData = _boardRepository.GetBoard(
                new BoardSearchSingleT
                {
                    Idx = id,
                    IsIncludeDeleteItem = false,
                    IsIncludeDisplayNoneItem = _isAdmin
                });

            var boardcreateVM = new BoardCreateVM
            {
                Idx = boardData.Idx,
                Title = HttpUtility.HtmlDecode(boardData.Title),
                Body = HttpUtility.HtmlDecode(boardData.Contents),
                SearchTag = boardData.SearchTag,
                WriteDate = boardData.UpdateDate == null ? boardData.InsertDate.ToString("yyyy-MM-dd HH:mm") : ((DateTime)boardData.UpdateDate).ToString("yyyy-MM-dd HH:mm"),
                IsDisplay = boardData.IsDisplay,
                Categories = boardData.Categories.ToArray(),
                WriteUserName = boardData.InsertUser.Name,
                WriteUserId = boardData.InsertUser.UserID
            };

            var list = _boardAutoSaveRepository.GetBoardAutoSaveList(MemberInfo.Instance.UserKey);
            if (list.Count > 0)
                boardcreateVM.IsExistBoardAutoSave = true;

            return View(boardcreateVM);
        }

        [HttpPost]
        [Authorize(Roles = "ADMIN")]
        public ActionResult Edit(BoardCreateVM model)
        {
            try
            {
                var data = new BoardT
                {
                    Idx = model.Idx,
                    Contents = model.Body,
                    Title = model.Title,
                    SearchTag = model.SearchTag,
                    IsDisplay = model.IsDisplay,
                    UpdateUser = new MemberT {UserKey = MemberInfo.Instance.UserKey}
                };

                if (model.Categories != null)
                {
                    data.Categories = model.Categories.Where(s => !string.IsNullOrEmpty(s)).Distinct().ToList();
                }

                var returnValue = _boardRepository.SetBoard(data);

                // 임시저장 데이터 삭제
                if (returnValue > 0)
                {
                    _boardAutoSaveRepository.RemoveBoardAutoSave(model.AutoSaveIdx, MemberInfo.Instance.UserKey);
                }

                return Json(new { Success = returnValue > 0, Idx = model.Idx });
            }
            catch
            {
                return View();
            }
        }

        [HttpPost]
        public ActionResult Delete(int id)
        {
            try
            {
                var returnValue = _boardRepository.RemoveBoard(id);

                return Json(new {Success = returnValue > 0});
            }
            catch
            {
                return Json(new { Success = false });
            }
        }

        [HttpPost]
        public async Task<ActionResult> UploadForCKEditor(HttpPostedFileBase upload, string CKEditorFuncNum, string CKEditor, string langCode)
        {
            var imagePath = await UploadHelper.UploadImageFromHttpPostedFile(upload);

            var output = string.Empty;
            if (!string.IsNullOrEmpty(imagePath))
            {
                output = @"<html><body><script>window.parent.CKEDITOR.tools.callFunction(" + CKEditorFuncNum + ", \"" + imagePath.ToImageUrl() + "\", \"\");</script></body></html>";
            }
            else
            {
                output = @"<script>alert('업로드에 실패하였습니다.');</script>";
            }
            return Content(output);
        }

        [HttpGet]
        public ActionResult GetCategoryList()
        {
            var boardtotalCount = _boardRepository.GetBoardListCount(new BoardSearchT
            {
                Category = "*",
                PageIndex = 1,
                PageSize = Int32.MaxValue,
                IsIncludeDeleteItem = false,
                IsIncludeDisplayNoneItem = false
            });

            var categoryList = _categoryRepository.GetTotalCategoryList();

            categoryList.Insert(0, new CategoryT { ArticleCount = boardtotalCount, BoardList = null, CategoryName = "*" });

            var jsonCategoryList = (from s in categoryList
                                    select new
                                    {
                                        categoryName = s.CategoryName,
                                        articleCount = s.ArticleCount
                                    }).ToList();

            return Json(new { CategoryData = jsonCategoryList }, JsonRequestBehavior.AllowGet);
        }

        [HttpGet]
        public ActionResult GetArticlesByDay()
        {
            var cacheName = "GetArticlesByDay";
            
            var cache = new CacheHelper<List<BoardT>>();

            var boardList = cache.GetCachedItem(cacheName);
            if (boardList == null)
            {
                boardList =
                    _boardRepository.GetBoardList(new BoardSearchT()
                    {
                        Category = "*",
                        PageIndex = 1,
                        PageSize = Int32.MaxValue,
                        IsIncludeDeleteItem = false,
                        IsIncludeDisplayNoneItem = false
                    });

                cache.AddToCache(cacheName, boardList, CacheHelperPriority.Default);
            }

            var tempList = boardList.Select(item => new BoardVM
            {
                Idx = item.Idx,
                Title = HttpUtility.HtmlDecode(item.Title),
                WriteDate = item.UpdateDate == null ? item.InsertDate.ToString("yyyy-MM-dd HH:mm") : ((DateTime)item.UpdateDate).ToString("yyyy-MM-dd HH:mm"),
            }).ToList();

            var jsonBoardList = (from s in tempList
                                    select new
                                    {
                                        s.Idx,
                                        s.Title,
                                        s.WriteDate,
                                    }).ToList();

            return Json(new { BoardData = jsonBoardList }, JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// 자동저장 등록
        /// </summary>
        [HttpPost]
        [Authorize(Roles = "ADMIN")]
        public ActionResult AutoSave(BoardAutoSaveVM model)
        {
            var data = new BoardAutoSaveT
            {
                TempIdx = model.TempIdx,
                UserKey = MemberInfo.Instance.UserKey,
                Title = model.Title ?? string.Empty,
                Contents = model.Contents ?? string.Empty,
                SearchTag = model.SearchTag ?? string.Empty
            };

            var nIdx = 0;

            if(data.TempIdx == 0)
                nIdx = _boardAutoSaveRepository.AddBoardAutoSave(data);
            else
                nIdx = _boardAutoSaveRepository.SetBoardAutoSave(data);

            return Json(new { autoSaveIdx = nIdx });
        }

        /// <summary>
        /// 자동저장 목록 불러오기
        /// </summary>
        [Authorize(Roles = "ADMIN")]
        public ActionResult AutoSaveList()
        {
            var dataList = _boardAutoSaveRepository.GetBoardAutoSaveList(MemberInfo.Instance.UserKey);

            var autoSaveDataList = dataList.Select(data => new BoardAutoSaveVM
            {
                UserKey = data.UserKey, 
                Title = data.Title, 
                Contents = data.Contents, 
                SearchTag = data.SearchTag, 
                InsertDate = data.InsertDate.ToString("yyyy-MM-dd HH:mm:ss"), 
                TempIdx = data.TempIdx,
            }).ToList();

            return Json(new {AutoSaveList = autoSaveDataList}, JsonRequestBehavior.AllowGet);
        }

        #region Privates

        private BoardListVM GetBoardList(bool isIncludeDeleteItem, bool isIncludeDisplayNoneItem)
        {
            const int pageSize = 5;
            var pageIndex = QueryStringHelper.GetInt("page", 1);

            var data = new BoardListVM();

            var boardSearchT = new BoardSearchT
            {
                PageIndex = pageIndex,
                PageSize = pageSize,
                Category = QueryStringHelper.GetString("category", "*"),
                SearchText = QueryStringHelper.GetString("searchtext", string.Empty),
                IsIncludeDeleteItem = isIncludeDeleteItem,
                IsIncludeDisplayNoneItem = isIncludeDisplayNoneItem
            };

            var boardData = _boardRepository.GetBoardList(boardSearchT);
            var boardDataCount = _boardRepository.GetBoardListCount(boardSearchT);

            var boardList = boardData.Select(item => new BoardVM
            {
                Idx = item.Idx,
                Title = HttpUtility.HtmlDecode(item.Title),
                TitleImageUrl = WebHelper.GetImageUrlFromHtml(HttpUtility.HtmlDecode(item.Contents)),
                Body = WebHelper.StripTagsCharArray(HttpUtility.HtmlDecode(item.Contents)),
                WriteDate = item.UpdateDate == null ? item.InsertDate.ToString("yyyy-MM-dd HH:mm") : ((DateTime)item.UpdateDate).ToString("yyyy-MM-dd HH:mm"),
                SearchTag = item.SearchTag,
                WriteUserName = item.InsertUser.Name, //item.UpdateUser.UserKey == 0 ? item.InsertUser.Name : item.UpdateUser.Name,
                WriteUserId = item.InsertUser.UserID //item.UpdateUser.UserKey == 0 ? item.InsertUser.UserID : item.UpdateUser.UserID
            }).ToList();

            data.BoardList = boardList;
            data.SearchData = new SearchObjVM
            {
                PageIndex = pageIndex,
                PageSize = pageSize,
                TotalCount = boardDataCount,
                Parameters = PagingHelper.GetParameterString(),
                PageCount = PagingHelper.GetPageCount(boardDataCount, pageSize)
            };

            return data;
        }

        #endregion
    }
}
